/**
 * Created by Administrator on 2017/2/16.
 */

var GlobalConfig = require('../../../../config/config.json');
var http = require("http");
var roomManager = require('../../../logic/world/roomManager');

// 手机验证码插件
var telephoneCodePlugin = require('../../../plugins/telephoneCode/telephoneCodePlugin_Netease');

module.exports = function (app) {
    return new Handler(app);
};

var Handler = function (app) {
    this.app = app;
};

var handler = Handler.prototype;

handler.setSignature = function (msg, session, next) {
    var self = this;
    var uid = session.uid;

    var signature = msg.signature;
    if (!signature || !(typeof signature == "string")) {
        next(null, {code: Code.ARGS_VALUE_WRONG});
        return;
    }

    if (signature.length > 32) {
        next(null, {code: Code.ARGS_LENGTH_LIMIT});
        return;
    }

    gPlayerManger.getPlayer(uid, function (player) {
        if (!player) {
            next(null, {code: Code.UID_INVALID});
            return;
        }

        player.user.info.signature = signature;
        player.markDirty("info");
        next(null, {});
    });
};

handler.query = function (msg, session, next) {
    msg.nolog = true;
    var uid = session.uid;

    if (isNaN(msg.target)) {
        next(null, {code: Code.ARGS_INVALID});
        return;
    }

    var targetUid = parseInt(msg.target);
    if (!targetUid) {
        next(null, {code: Code.ARGS_VALUE_WRONG});
        return;
    }

    async.waterfall([
        function (cb) {
            gPlayerManger.getPlayer(uid, function (p) {
                cb((p) ? null : Code.DB_ERROR, p);
            });
        }, function (player, cb) {
            gPlayerManger.getPlayer(targetUid, function (p) {
                cb((p) ? null : Code.UID_INVALID, player, p);
            });
        }, function (player, target, cb) {
            if (!player.getGmLevel()) {
                cb(Code.GM_NOT_AGENT);
                return;
            }

            next(null, {"user": target.user});
            cb();
        }
    ], function (err) {
        if (err) {
            next(err, {code: err});
        }
    });
}

handler.checkPresent = function (msg, session, next) {
    msg.nolog = true;
    var uid = session.uid;

    if (isNaN(msg.target) || !msg.resource) {
        next(null, {code: Code.ARGS_INVALID});
        return;
    }

    var targetUid = parseInt(msg.target);
    if (!targetUid) {
        next(null, {code: Code.ARGS_VALUE_WRONG});
        return;
    }

    if (targetUid == uid) {
        next(null, {code: Code.UID_IS_SELF});
        return;
    }

    async.waterfall([
        function (cb) {
            gPlayerManger.getPlayer(uid, function (p) {
                cb((p) ? null : Code.DB_ERROR, p);
            });
        }, function (player, cb) {
            gPlayerManger.getPlayer(targetUid, function (p) {
                cb((p) ? null : Code.UID_INVALID, player, p);
            });
        }, function (player, target, cb) {
            if (!!msg.resource) {
                if (!player.getResource(msg.resource)) {
                    cb(Code.RESOURCE_NOT_EXIST);
                    return;
                }
                if (!player.checkResource(msg.resource, msg.num)) {
                    cb(Code.LACK_OF_RESOURCE);
                    return;
                }
            }
            else {
                if (!player.getGmLevel()) {
                    cb(Code.GM_NOT_AGENT);
                    return;
                }
            }

            next(null, {'user': target.user});
            cb();
        }
    ], function (err) {
        if (err) {
            next(err, {code: err});
        }
    });
};

handler.presentPay = function (msg, session, next) {
    var uid = session.uid;

    if (isNaN(msg.target) || isNaN(msg.num)) {
        next(null, {code: Code.ARGS_INVALID});
        return;
    }

    var targetUid = parseInt(msg.target);
    var num = parseInt(msg.num);
    if (!targetUid || !num) {
        next(null, {code: Code.ARGS_VALUE_WRONG});
        return;
    }

    if (targetUid == uid) {
        next(null, {code: Code.UID_IS_SELF});
        return;
    }

    async.waterfall([
        function (cb) {
            gPlayerManger.getPlayer(uid, function (p) {
                cb((p) ? null : Code.DB_ERROR, p);
            });
        }, function (player, cb) {
            gPlayerManger.getPlayer(targetUid, function (p) {
                cb((p) ? null : Code.UID_INVALID, player, p);
            });
        }, function (player, target, cb) {
            if (!player.checkResource('card', num)) {
                cb(Code.LACK_OF_CARD);
                return;
            }

            player.alterResource('card', -num, 'payTo');
            target.payCard(num);

            var now = new Date();
            DB.pay.save({
                agent: player.uid,
                uid: target.uid,
                num: num,
                t: now.stdFormatedString()
            });

            async.series([
                function (cb) {
                    var sql = util.format('INSERT INTO %spay(user_id, uid, uname, number, `status`, add_time) value(%d, %d, %s, %d, %d, %d)',
                        GlobalConfig.mysql.prefix, player.uid, target.uid, SQL.escape(target.user.info.name), num, 1, now.getStamp());
                    SQL.query(sql, function (err, results) {
                        if (err) {
                            logger.error('uid=%d userHandler.pay sql=%s err=%j', uid, sql, err.message);
                        }
                        cb(err);
                    });
                },
                function (cb) {
                    var sql = util.format('UPDATE %suser SET total_give=total_give+%d WHERE user_id=%d',
                        GlobalConfig.mysql.prefix, num, player.uid);
                    SQL.query(sql, function (err, results) {
                        if (err) {
                            logger.error('uid=%d userHandler.pay sql=%s err=%j', uid, sql, err.message);
                        }
                        cb();
                    });
                },
                function (cb) {
                    var sql = util.format('UPDATE %suser SET total_amount=total_amount+%d WHERE user_id=%d',
                        GlobalConfig.mysql.prefix, num, target.uid);
                    SQL.query(sql, function (err, results) {
                        if (err) {
                            logger.error('uid=%d userHandler.pay sql=%s err=%j', uid, sql, err.message);
                        }
                        cb();
                    });
                }
            ], function (err) {

            });

            next(null, {'status': target.user.status});
            cb();
        }
    ], function (err) {
        if (err) {
            next(err, {code: err});
        }
    });
};

handler.pay = function (msg, session, next) {
    var uid = session.uid;

    if (isNaN(msg.target) || isNaN(msg.num)) {
        next(null, {code: Code.ARGS_INVALID});
        return;
    }

    var targetUid = parseInt(msg.target);
    var num = parseInt(msg.num);
    if (!targetUid || !num) {
        next(null, {code: Code.ARGS_VALUE_WRONG});
        return;
    }

    async.waterfall([
        function (cb) {
            gPlayerManger.getPlayer(uid, function (p) {
                cb((p) ? null : Code.DB_ERROR, p);
            });
        }, function (player, cb) {
            gPlayerManger.getPlayer(targetUid, function (p) {
                cb((p) ? null : Code.UID_INVALID, player, p);
            });
        }, function (player, target, cb) {
            if (!player.getGmLevel()) {
                cb(Code.GM_NOT_AGENT);
                return;
            }

            if (!player.checkResource('card', num)) {
                cb(Code.LACK_OF_CARD);
                return;
            }

            player.alterResource('card', -num, "payTo");
            target.payCard(num);

            var now = new Date();
            DB.pay.save({
                agent: player.uid,
                uid: target.uid,
                num: num,
                t: now.stdFormatedString()
            });

            async.series([
                function (cb) {
                    var sql = util.format("INSERT INTO %spay(user_id, uid, uname, number, `status`, add_time) value(%d, %d, %s, %d, %d, %d)",
                        GlobalConfig.mysql.prefix, player.uid, target.uid, SQL.escape(target.user.info.name), num, 1, now.getStamp());
                    SQL.query(sql, function (err, results) {
                        if (err) {
                            logger.error("uid=%d userHandler.pay sql=%s err=%j", uid, sql, err.message);
                        }
                        cb(err);
                    });
                },
                function (cb) {
                    var sql = util.format("UPDATE %suser SET total_give=total_give+%d WHERE user_id=%d",
                        GlobalConfig.mysql.prefix, num, player.uid);
                    SQL.query(sql, function (err, results) {
                        if (err) {
                            logger.error("uid=%d userHandler.pay sql=%s err=%j", uid, sql, err.message);
                        }
                        cb();
                    });
                },
                function (cb) {
                    if (!target.getGmLevel()) {
                        cb();
                    }

                    var sql = util.format("UPDATE %suser SET total_amount=total_amount+%d WHERE user_id=%d",
                        GlobalConfig.mysql.prefix, num, target.uid);
                    SQL.query(sql, function (err, results) {
                        if (err) {
                            logger.error("uid=%d userHandler.pay sql=%s err=%j", uid, sql, err.message);
                        }
                        cb();
                    });
                }
            ], function (err) {

            });


            next(null, {"status": target.user.status});
            cb();
        }
    ], function (err) {
        if (err) {
            next(err, {code: err});
        }
    });
}

handler.payList = function (msg, session, next) {
    msg.nolog = true;
    var uid = session.uid;

    // 新增查询对应给玩家的赠送历史
    var targetId = isNaN(msg.targetId) ? 0 : parseInt(msg.targetId);

    var sql = "";
    if (targetId) {
        sql = util.format("SELECT user_id,uid,uname,number,status,add_time FROM %spay where user_id=%d AND uid=%d ORDER BY add_time DESC LIMIT 20",
            GlobalConfig.mysql.prefix, uid, targetId);
    } else {
        sql = util.format("SELECT user_id,uid,uname,number,status,add_time FROM %spay where user_id=%d ORDER BY add_time DESC LIMIT 20",
            GlobalConfig.mysql.prefix, uid);
    }

    SQL.query(sql, function (err, results) {
        if (err) {
            logger.error("uid=%d userHandler.payList SQL err=%j", uid, err.message);
        }
        next(null, {"arr": results});
    });
};
handler.payment = function (msg, session, next) {
    var channel = msg.channel;
    var woodID = msg.goodId;
    var payUrlName = GlobalConfig["channel"][channel];

    if (!payUrlName) {
        next(Code.ARGS_INVALID, {code: Code.ARGS_INVALID});
        return;
    }
    var uid = session.uid;
    async.waterfall([
        function (cb) {
            gPlayerManger.getPlayer(uid, function (thePlayer) {
                var player = thePlayer;
                if (!thePlayer) {
                    cb(Code.DB_ERROR);
                    return;
                }
                cb(null, player, uid);
            });
        },
        function (player, uid, cb) {
            var orderNo = payUrlName + Date.parse(new Date()) + parseInt(Math.random() * 100 % 100);
            var config = gGlobalManager.getConfig("payment");

            var rate = config[woodID];
            if (!rate) {
                next(null, {code: Code.ARGS_INVALID});
                cb({code: Code.ARGS_INVALID});
                return;
            }
            var money = rate["payMoney"];

            var sets = {
                "_id": orderNo,
                "platform": channel,
                "status": 0,
                "bank": "",
                "uid": uid,
                "money": money,
                "item": woodID,
                "time": Date.parse(new Date())
            };

            DB.onlinepay.save(sets, function (err) {
                if (err) {
                    cb(Code.DB_ERROR);
                    console.log("save errr");
                    return;
                }
                cb(null, player, uid, money, orderNo);
            });
        },
        function (player, uid, money, orderNo, cb) {

            var url = GlobalConfig["payment"][payUrlName].concat("?", "body=", "ali_app", "&",
                "subject=", "pay", "&", "amount=", money, "&", "return_param=", "123321", "&", "client_ip=",
                player.user.marks.loginIP, "&", "orderNo=", orderNo);
            console.log(url);
            http.get(url, function (res) {
                var statusCode = res.statusCode;
                var contentType = res.headers['content-type'];
                var error;
                if (statusCode !== 200) {
                    error = new Error("Request Failed.\n" +
                        "Status Code: ${statusCode}");
                    console.log(statusCode)
                    cb(Code.NETWORK_ERROR);
                }
                // else if (!/^application\/json/.test(contentType)) {
                //     error = new Error("Invalid content-type.\n" +
                //         "Expected application/json but received ");
                //     console.log(contentType);
                // }
                if (error) {

                    // consume response data to free up memory
                    res.resume();
                    cb(Code.NETWORK_ERROR);
                    return;
                }
                res.setEncoding('utf8');
                var rawData = '';
                res.on('data', function (chunk) {
                    rawData += chunk
                });
                res.on('end', function () {
                    try {
                        //let parsedData = JSON.parse(rawData);
                        var parsedData = rawData;

                        next(null, {"orderInfo": parsedData});

                    } catch (e) {

                        cb(Code.NETWORK_ERROR);
                    }
                });

            }).on('error', function (e) {
                console.log("Got error: ");
                console.log(e.message);
                cb(Code.NETWORK_ERROR);
            });
        }
    ], function (code) {
        if (code) {
            next(null, {code: code, route: ""});
            return;
        }
    });

}
handler.queryCreatRooms = function (msg, session, next) {
    var self = this;
    var uid = session.uid;
    var rids = roomManager.queryCreatRooms(uid).map(function (v) {
        return v['rid'];
    });
    console.log(rids);
    if (rids.length == 0) {
        next(null, {"rooms": []});
    } else {
        // var info = rids.map(function (v) {
        //     roomManager.getRoom(v)
        // });
        console.log(rids);
        //msg['rids'] = rids;
        var infos = [];
        var indexs = roomManager.queryCreatRooms(uid);
        var totalPlayer = 0;
        async.each(rids, function (rid, cb) {
            session.set('rid', rid);
            msg.rid = rid;
            self.app.rpc.game.roomRemote.query(session, uid, msg, function (code, info) {
                if (code) {
                    roomManager.delRoom(rid);
                    cb(code);
                    return;
                }
                indexs.forEach(function (item) {
                    if (item.index && item.rid == info.id) {
                        info["index"] = item.index;
                    }
                });
                totalPlayer += info.playerNum;
                info["playing"] = false;
                info["rid"] = info.id;
                if (info.curRound > 0) {
                    info["playing"] = true;
                }
                infos.push(info);
                cb();
            });
        }, function (err) {
            if (err) {
                console.log(err);
                next(err);
            } else {
                console.log("infoof")
                console.log(infos);
                next(null, {"rooms": infos, "totalPlayer": totalPlayer});
            }

        })
    }


    //next(null, { "rooms": info });
}
/***
 * 贵溪强制解散房间
 * @param msg
 * @param session
 * @param next
 */
handler.compelDestroy = function (msg, session, next) {
    var self = this;
    var uid = session.uid;
    var rid = msg.rid;
    if (!rid) {
        next(Code.ARGS_INVALID);
        return;
    }

    session.set('rid', rid);
    self.app.rpc.game.roomRemote.compelDestroy(session, uid, {"rid": rid}, function (err, result) {
        if (err) {
            next(err);
        } else {
            next(null, {"destroy": result.destroy});
        }
    });
}

handler.queryPlayerNumOfAgency = function (msg, session, next) {
    var self = this;
    var uid = session.uid;
    var rids = roomManager.queryCreatRooms(uid).map(function (v) {
        return v['rid'];
    });
    console.log(rids);
    if (rids.length == 0) {
        next(null, {"playerNum": 0});
    } else {
        var totalPlayer = 0;
        async.each(rids, function (rid, cb) {
            session.set('rid', rid);
            msg.rid = rid;
            self.app.rpc.game.roomRemote.query(session, uid, msg, function (code, info) {
                if (code) {
                    roomManager.delRoom(rid);
                    cb(code);
                    return;
                }
                totalPlayer += info.playerNum;
                cb();
            });
        }, function (err) {
            if (err) {
                console.log(err);
                next(err);
            } else {
                next(null, {"totalPlayer": totalPlayer});
            }
        })
    }
}

//-----------------------------------------------------------------------------

// 查询玩家数据
handler.queryUser = function(msg, session, next) {
    var self = this;
    var targetUid = msg.targetUid;

    gPlayerManger.getPlayer(targetUid, function (player) {
        if (!player) {
            next(null, {code: Code.UID_INVALID});
            return;
        }

        next(null, {
            player: {
                uid: player.uid,                            // 玩家编号
                info: {
                    name: player.user.info.name,            // 玩家名字
                    headpic: player.user.info.headpic,      // 玩家头像
                    sex: player.user.info.sex               // 玩家性别
                }
            }
        });
    });
}

// 赠送房卡
handler.presentCard = function(msg, session, next) {
    var self = this;
    var uid = session.uid;
    var targetUid = msg.targetUid;
    var num = +msg.num;

    var curPlayer = null;
    var targetPlayer = null;

    if (isNaN(num) || (num <= 0)) {
        next(null, { code: Code.PRESENT_CARD_INVALID_NUM });
        return;
    }

    async.series([function(cb){ // 查询当前玩家
        gPlayerManger.getPlayer(uid, function (player) {
            if (!player) {
                cb(Code.UID_INVALID);
                return;
            }
            curPlayer = player;
            cb();
        });
    }, function(cb){ // 查询目标玩家
        gPlayerManger.getPlayer(targetUid, function (player) {
            if (!player) {
                cb(Code.UID_INVALID);
                return;
            }
            targetPlayer = player;
            cb();
        });
    }, function(cb) { // 房卡操作
        var code = curPlayer.checkResourceCode("card", num);
        if (code != Code.SUCCESS) {
            cb(code);
        } else {
            curPlayer.costResource("card", num, "PRESENT-" + targetUid);
            targetPlayer.addResource("card", num, "PRESENT-" + uid);
            cb();
        }
    }], function(err){
        next(num, { code: err ? err : Code.SUCCESS });
    });
};

// 发送手机验证码
handler.sendTelephoneCode = function(msg, session, next) {
    var self = this;
    var uid = session.uid;
    var telephone = msg.telephone;  // 手机号码

    async.waterfall([function(cb){  // 查询玩家
        gPlayerManger.getPlayer(uid, function (player) {
            cb(player ? 0 : Code.UID_INVALID, player);
        });
    }, function(player, cb) {
        var userTelephone = player.getTelephone();
        if (userTelephone.code != 0) {
            cb(Code.TELEPHONE_CODE_ALREADY_SEND);
        } else if(userTelephone.number != 0) {
            cb(Code.TELEPHONE_ALREADY_SET);
        } else {
            telephoneCodePlugin.sendCode(telephone, function(err, res){
                if (err) {  // 发生错误
                    cb(Code.SYSTEM_ERROR);
                } else {
                    if (res.code == 200) {  // 发送成功
                        var verifyCode = +res.obj;
                        logger.info("Telephone VerifyCode: " + telephone + " -> " + verifyCode);

                        player.setTelephoneCode(verifyCode);
                        next(null, { code: Code.SUCCESS });
                        cb();
                    } else {    // 验证码发送失败
                        cb(Code.TELEPHONE_CODE_SEND_FAILED);
                    }
                }
            });
        }
    }], function(code){
        if (code) {
            next(null, { code: code });
        }
    });
};

// 绑定手机号码
handler.setTelephone = function(msg, session, next) {
    var self = this;
    var uid = session.uid;
    var telephone = msg.telephone;              // 手机号码
    var telephoneCode = msg.telephoneCode;      // 验证码

    async.waterfall([function(cb){  // 查询玩家
        gPlayerManger.getPlayer(uid, function (player) {
            cb(player ? 0 : Code.UID_INVALID, player);
        });
    }, function(player, cb) {
        var userTelephone = player.getTelephone();
        if (userTelephone.code != telephoneCode) {  // 验证码错误
            cb(Code.TELEPHONE_CODE_ERROR);
        } else if (userTelephone.number != 0) { // 手机号码已经绑定
            cb(Code.TELEPHONE_ALREADY_SET);
        } else {    // 绑定手机号
            player.setTelephone(telephone);

            next(null, { code: Code.SUCCESS} );

            cb();
        }
    }], function(code){
        if (code) {
            next(null, { code: code });
        }
    });
};

// 获取邮件列表
handler.getMails = function(msg, session, next){
    var self = this;
    var uid = session.uid;

    gPlayerManger.getPlayer(uid, function (player) {
        if (!player) {
            cb(Code.UID_INVALID);
            return;
        }

        next(null, { mails: player.getMails() });
    });
};

// 更新邮件
handler.updateMail = function(msg, session, next) {
    var self = this;
    var uid = session.uid;
    var mailId = msg.mailId;

    gPlayerManger.getPlayer(uid, function (player) {
        if (!player) {
            cb(Code.UID_INVALID);
            return;
        }

        player.updateMail(mailId);

        next(null, { code: Code.SUCCESS });
    });
};